package coffeenc.mall.security.config;

import coffeenc.mall.common.jwt.JwtTokenUtil;
import coffeenc.mall.security.component.JwtAuthenticationTokenFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * URL白名单
     */
    @Autowired
    IgnoreUrlsConfig ignoreUrlsConfig;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
    }

    protected void configure(HttpSecurity http) throws Exception{
        /**
         * URL拦截配置器
         */
        ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = http.authorizeRequests();
        /**
         * 允许所有人访问白名单中的URL
         */
        for (String url : ignoreUrlsConfig.getUrls()){
            registry.antMatchers(url)
                    .permitAll();
        }
        /**
         * 同意用于申请跨域的OPTIONS请求
         */
        registry.antMatchers(HttpMethod.OPTIONS).permitAll();
        /**
         * 任何请求都需要认证
         */
        http.authorizeRequests().anyRequest().authenticated();
        /**
         * 关闭csrf防护
         */
        http.csrf().disable();
        /**
         *  添加自定义的JWT登录支持过滤链
         */
        http.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
    @Bean
    JwtTokenUtil jwtTokenUtil(){return new JwtTokenUtil();}
    @Bean
    JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter(){return new JwtAuthenticationTokenFilter();}
}